package com.example.sql.manager.service.impl;

import com.alibaba.fastjson.JSON;
import com.example.sql.manager.config.FuncProperties;
import com.example.sql.manager.dao.FuncDao;
import com.example.sql.manager.entity.po.FuncPO;
import com.example.sql.manager.enums.Enabled;
import com.example.sql.manager.enums.SQLType;
import com.example.sql.manager.ftl.FtlParser;
import com.example.sql.manager.service.InvokeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Objects;

@Service
@Slf4j
@Transactional
public class InvokeServiceImpl implements InvokeService {

    @Resource
    private FuncDao funcDao;

    @Resource
    private NamedParameterJdbcTemplate template;

    @Resource
    private FuncProperties funcProperties;

    @Override
    public Object func(Long id, Map<String, Object> params) throws Exception {
        FuncPO dbFunc = this.funcDao.selectById(id);
        if (Objects.isNull(dbFunc)) {
            throw new RuntimeException("This function does not exist!!!");
        }
        String content = dbFunc.getContent();
        String sql = FtlParser.parseToSql(content, params);
        log.info("InvokeServiceImpl.func#\r\nParsed Sql: {}", sql);
        log.info("InvokeServiceImpl.func#\r\nParams: {}", JSON.toJSONString(params));
        assert sql != null;
        if (dbFunc.getSqlType() == SQLType.SELECT.getVal() && dbFunc.getEnabled() == Enabled.ENABLED.getVal()) {
            return this.template.queryForList(sql, params);
        }
        if (dbFunc.getSqlType() == SQLType.UPDATE.getVal() && dbFunc.getEnabled() == Enabled.ENABLED.getVal()) {
            //系统配置可以更新数据库的情况下，才能继续进行下面括号内的逻辑
            if (funcProperties.getCanUpdateDb()) {
                return this.template.update(sql, params);
            }
        }
        throw new RuntimeException("Nothing to do!!!");
    }

    @Override
    public Object query(Long id, Map<String, Object> params) throws Exception {
        return this.func(id, params);
    }

    @Override
    public Object update(Long id, Map<String, Object> params) throws Exception {
        return this.func(id, params);
    }

}
